package com.lolan.training.libreoffice.controllers;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;

import com.lolan.training.libreoffice.services.LibreOfficeService;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.util.FileUtils;
import org.jodconverter.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.lolan.training.common.constants.ErrorCode;
import com.lolan.training.common.entity.ResponseObject;

/** Controller providing conversion endpoints. */
@RestController
@RequestMapping("/office")
@ConditionalOnProperty(name = "jodconverter.local.enabled", havingValue = "true")
public class LibreOfficeController {

	@Autowired
	private LibreOfficeService loSvc;

	@SuppressWarnings("SameReturnValue")
	@GetMapping("/")
		/* default */String index() {
		return "Converter";
	}


	private LogLevel resolveLogLevel(String level) {
		String trimmedLevel = level.trim();
		return LogLevel.valueOf(trimmedLevel.toUpperCase(Locale.ENGLISH));
	}
	// 修改上面的changeLevel方法
	// 将要设置的日志记录器名称也通过参数传递
	@GetMapping("/level")
	public Object changeLevel(String name, String level) {
		LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader());
		// 如果日志记录器名称传入的是root，那么将其设置为null
		if (name.equalsIgnoreCase("root")) {
			name = null;
		}
		// 只要将name置为null，那么整个系统的级别都将一同进行调整
		system.setLogLevel(name, resolveLogLevel(level)) ;
		return "change logger level success" ;
	}

	/**
	 * Converts a souirce file to a target format.
	 *
	 * @param inputFile    Source file to convert.
	 * @param outputFormat Output format of the conversion.
	 * @return The converted file, or the error redirection if an error occurs.
	 */
	@PostMapping("/convert")
	/* default */Object convert(
			@RequestParam("inputFile") final MultipartFile inputFile,
			@RequestParam(name = "outputFormat", required = false) final String outputFormat) {
		if (inputFile.isEmpty()) {
			return ResponseObject.getErrorResponse(ErrorCode.E900001);
		}

		if (StringUtils.isBlank(outputFormat)) {
			return ResponseObject.getErrorResponse(ErrorCode.E900002);
		}

		// Here, we could have a dedicated service that would convert document
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
			final DocumentFormat targetFormat = DefaultDocumentFormatRegistry.getFormatByExtension(
					outputFormat);
			Assert.notNull(targetFormat, ErrorCode.E900003.toString());
//			converter
//					.convert(inputFile.getInputStream())
//					.to(baos)
//					.as(targetFormat)
//					.execute();
			loSvc.doConvert(inputFile.getInputStream(), targetFormat, Objects.requireNonNull(inputFile.getOriginalFilename()), baos);

			final HttpHeaders headers = new HttpHeaders();
			headers.setContentType(
					MediaType.parseMediaType(targetFormat.getMediaType()));
			headers.add(
					"Content-Disposition",
					"attachment; filename=" +
							FileUtils.getBaseName(inputFile.getOriginalFilename()) +
							"." +
							targetFormat.getExtension());
			return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.OK);
		} catch (OfficeException | IOException e) {
			e.printStackTrace();
			return ResponseObject.getErrorResponse(ErrorCode.E900004);
		} catch (IllegalArgumentException e) {
			return ResponseObject.getErrorResponse(ErrorCode.valueOf(e.getMessage()));
		} catch (Exception e) {
			e.printStackTrace();
			return ResponseObject.getErrorResponse(ErrorCode.E999999);
		}
	}

}
